package com.smproject.utils;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.date.DateUtil;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.smproject.config.mongodb.entity.User;
import com.smproject.entity.SysUserInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Component;

import java.sql.Timestamp;
import java.util.*;

/**
 * mongoDB的工具类
 * @author hu.liang
 * @Date 2019/7/4 0004
 */
@Component
public class MongoUtils {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 保存或者是更新
     * @param obj
     * @param id
     */
    public void save(Object obj,Integer id,Class cls){
        if(Objects.nonNull(id)&&!Objects.equals(id,0)){
            //更新
            Query query = new Query();
            query.addCriteria(Criteria.where("id").is(id));
            List list = this.mongoTemplate.find(query, cls);
            if(Objects.nonNull(list)&&list.size()>0){
                Object oldObj = list.get(0);
                BeanUtil.copyProperties(obj,oldObj,new CopyOptions(null,true));
                this.mongoTemplate.save(oldObj);
            }else{
                this.mongoTemplate.insert(obj);
            }
        }else{
            this.mongoTemplate.insert(obj);
        }
    }

    /**
     * 查询详情
     * @param id
     * @return
     */
    public Object findOne(Integer id,Class cls){
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(id));
        Object obj = this.mongoTemplate.findOne(query,cls);
        if(Objects.nonNull(obj)){
            return obj;
        }
        return null;
    }

    /**
     * 查询列表的数据
     * @param cls
     * @return
     */
    public Object findList(Class cls){
        Query query = new Query();
        Object obj = this.mongoTemplate.find(query,cls);
        if(Objects.nonNull(obj)){
            return obj;
        }
        return null;
    }

    /**
     * 带查询条件的列表查询
     * @param param
     * @param cls
     * @return
     */
    public Object findList(Map<String,Object> param,Class cls){
        Query query = new Query();
        //查询条件封装
        findParam(param,query);
        Object obj = this.mongoTemplate.find(query,cls);
        if(Objects.nonNull(obj)){
            return obj;
        }
        return null;
    }

    /**
     * 查询带分页的数据
     * @param param
     * @param cls
     * @return
     */
    public Map<String,Object> findPageList(Map<String,Object> param,Class cls){
        //返回的数据
        Map<String,Object> result = new HashMap<>();
        //查询分页数数据
        Integer pageNo = Integer.parseInt(param.get("pageNo").toString());
        Integer pageSize = Integer.parseInt(param.get("pageSize").toString());
        pageNo = (pageNo-1)*pageSize;
        Query query = new Query();
        //若存在分页的字段时 则表示需要移除该字段
        if(param.containsKey("pageNo")){
            param.remove("pageNo");
        }
        if(param.containsKey("pageSize")){
            param.remove("pageSize");
        }
        //查询条件封装
        findParam(param,query);
        query.skip(pageNo).limit(pageSize);
        Object obj = this.mongoTemplate.find(query,cls);
        result.put("pageList",obj);
        //查询数据的列表的数据
        List pageList = (List)findList(param, cls);
        result.put("pageTotal",pageList.size());
        return result;
    }


    /**
     * 封装查询条件
     * @param param
     * @param query
     */
    private void findParam(Map<String,Object> param,Query query){
        if(Objects.nonNull(param)&&param.size()>0){
            for(Map.Entry<String,Object> obj : param.entrySet()){
                //若是值为int型
                if(obj.getValue() instanceof Integer){
                    query.addCriteria(Criteria.where(obj.getKey()).is(obj.getValue()));
                }
                //若是字符串
                if(obj.getValue() instanceof String){
                    query.addCriteria(Criteria.where(obj.getKey()).regex(obj.getValue().toString()));
                }
                //时间
                if(obj.getValue() instanceof Timestamp){
                    query.addCriteria(Criteria.where("startDate").gte(DateUtil.parse(param.get("startDate").toString())));
                    query.addCriteria(Criteria.where("endDate").lte(DateUtil.parse(param.get("endData").toString())));
                }
                if(obj.getValue() instanceof Date){
                    query.addCriteria(Criteria.where("startDate").gte(DateUtil.parse(param.get("startDate").toString())));
                    query.addCriteria(Criteria.where("endDate").lte(DateUtil.parse(param.get("endData").toString())));
                }
                if(obj.getValue() instanceof java.sql.Date){
                    query.addCriteria(Criteria.where("startDate").gte(DateUtil.parse(param.get("startDate").toString())));
                    query.addCriteria(Criteria.where("endDate").lte(DateUtil.parse(param.get("endData").toString())));
                }
            }
        }
    }


    /**
     * 根据删除数据
     * @param id
     * @param cls
     */
    public void  delete(Integer id,Class cls) {
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(id));
        Object obj = this.mongoTemplate.findOne(query, cls);
        if(Objects.nonNull(obj)){
            this.mongoTemplate.remove(query,cls);
        }
    }

    /**
     * 查询表中最大的id
     * @param obj
     * @return
     */
    public Integer getMaxId(Object obj){
        List<Integer> ids = new ArrayList<>();
        Query query = new Query();
        Integer id = 0;
        //用户
        if(obj instanceof User){
            List<User> list = this.mongoTemplate.find(query, User.class);
            if(Objects.nonNull(list)&&list.size()>0){
                for(User user : list){
                    ids.add(user.getId());
                }
            }
        }
        if(Objects.nonNull(ids)&&ids.size()>0){
            id = Collections.max(ids);
        }
        return (id+1);
    }
}
